#ifndef BLDCMotor_h
#define BLDCMotor_h

#include "Arduino.h"
#include "common/base_classes/FOCMotor.h"
#include "common/base_classes/Sensor.h"
#include "common/base_classes/BLDCDriver.h"
#include "common/foc_utils.h"  //utils 存放工具类函数常用工具
#include "common/time_utils.h"
#include "common/defaults.h"

/**
 BLDC motor class
*/
class BLDCMotor: public FOCMotor
{
  public:
    /**
     BLDCMotor class constructor       无刷电机类构造函数
     @param pp pole pairs number       极对数
     @param R  motor phase resistance  电机相电阻 说明这个可以设置
     */ 
    BLDCMotor(int pp,  float R = NOT_SET);
    
    /**
     * Function linking a motor and a foc driver 
     * 
     * @param driver BLDCDriver class implementing all the hardware specific functions necessary PWM setting
     */
    void linkDriver(BLDCDriver* driver);

    /** 
      * BLDCDriver link:
      * - 3PWM 
      * - 6PWM 
    */
    BLDCDriver* driver; 
    
    /**  Motor hardware init function
     * C++11 中的 override 关键字，可以显式的在派生类中声明，哪些成员函数需要被重写，如果没被重写，则编译器会报错。
     * */
  	void init() override;
    /** Motor disable function */
  	void disable() override;
    /** Motor enable function */
    void enable() override;

    /**
     * Function initializing FOC algorithm
     * and aligning sensor's and motors' zero position
     * 函数初始化FOC算法
     * 并且调整传感器和电机的零位
     */  
    int initFOC( float zero_electric_offset = NOT_SET , Direction sensor_direction = Direction::CW) override;
    /**
     * Function running FOC algorithm in real-time
     * 函数运行实时的Foc算法
     * it calculates the gets motor angle and sets the appropriate voltages
     * 它计算得到电机角度和设置适当的电压
     * to the phase pwm signals
     * 为相位PWM信号
     * - the faster you can run it the better Arduino UNO ~1ms, Bluepill ~ 100us
     * 运行速度越快越好Arduino UNO ~1ms, BLuepill ~ 100us
     */ 
    void loopFOC() override;

    /**
     * Function executing the control loops set by the controller parameter of the BLDCMotor.
     * 执行无刷直流电机控制器参数设置的控制回路的函数。
     * 
     * @param target  Either voltage, angle or velocity based on the motor.controller
     *                参数目标电压，角度或速度取决于电机。
     *                If it is not set the motor will use the target set in its variable motor.target
     *                控制器如果没有设置，电机将使用变量motor.target
     * This function doesn't need to be run upon each loop execution - depends of the use case
     * 这个函数不需要在每次循环执行时运行-取决于用例
     */
    void move(float target = NOT_SET) override;
    
    float Ua, Ub, Uc;//!< Current phase voltages Ua,Ub and Uc set to motor
                    //!给电机设置当前的相位电压Ua，Ub和Uc
    float	Ualpha, Ubeta; //!< Phase voltages U alpha and U beta used for inverse Park and Clarke transform
                           //!<相位电压U alpha和U beta用于逆Park和CLarke变换

  private:
    // FOC methods 
    /**
    * Method using FOC to set Uq to the motor at the optimal angle
    * 方法使用Foc算法在最佳角度上设置去电机的Uq
    * Heart of the FOC algorithm
    * FOC算法的核心
    * @param Uq Current voltage in q axis to set to the motor
    *           当前设置在电机q轴的电压
    * @param Ud Current voltage in d axis to set to the motor
    *           当前设置在电机d轴的电压
    * @param angle_el current electrical angle of the motor
    *           当前电机的电气角度
    */
    void setPhaseVoltage(float Uq, float Ud, float angle_el);
    /** Sensor alignment to electrical 0 angle of the motor */
    /** 传感器对准电机的电气0角 */
    int alignSensor();
    /** Current sense and motor phase alignment */
    /** 电流检测和电机相位校准 */
    int alignCurrentSense();
    /** Motor and sensor alignment to the sensors absolute 0 angle  */
    /** 电机和传感器对准传感器绝对0角 */
    int absoluteZeroSearch();

        
    // Open loop motion control    
    /**
     * Function (iterative) generating open loop movement for target velocity
     * it uses voltage_limit variable
     * 函数(迭代)生成开环运动的目标速度，它使用voltage_Limit变量
     * @param target_velocity - rad/s
     */
    float velocityOpenloop(float target_velocity);
    /**
     * Function (iterative) generating open loop movement towards the target angle
     * it uses voltage_limit and velocity_limit variables
     * 函数(迭代)生成朝向目标角度的开环运动，它使用voltage_Limit和速度限制变量
     * @param target_angle - rad
     */
    float angleOpenloop(float target_angle);
    // open loop variables
    long open_loop_timestamp;
};


#endif
